package model

import (
	"fmt"
	"gpt-api/framework/db"
	"strconv"
	"time"

	"github.com/spf13/viper"
)

type WxPay struct {
	db.BaseModel
	UserID      uint64    `json:"user_id" gorm:"column:user_id;type:int;default:0;comment:用户ID"`
	Type        string    `json:"type" gorm:"column:type;type:varchar(50);default:'';comment:支付类型,jf:积分充值"`
	TopupWaysId uint64    `json:"topup_ways_id" gorm:"column:topup_ways_id;type:int;default:0;comment:充值方式id"`
	TradeType   string    `json:"trade_type" gorm:"column:trade_type;type:varchar(50);default:'';comment:交易类型,JSAPI:公众号支付,NATIVE:扫码支付,APP:APP支付,MICROPAY:付款码支付,MWEB:H5支付,FACEPAY:刷脸支付"`
	TradeState  string    `json:"trade_state" gorm:"column:trade_state;type:varchar(50);default:'';comment:交易状态,SUCCESS:支付成功,REFUND:转入退款,NOTPAY:未支付,CLOSED:已关闭,REVOKED:已撤销（仅付款码支付会返回）,USERPAYING:用户支付中（仅付款码支付会返回）,PAYERROR:支付失败（仅付款码支付会返回）"`
	SuccessTime time.Time `json:"success_time" gorm:"column:success_time;type:timestamptz;default:null;comment:支付完成时间"`
	AmountTotal uint      `json:"amount_total" gorm:"column:amount_total;type:int;default:0;comment:支付金额，单位为分"`
	OutTradeNo  string    `json:"out_trade_no" gorm:"column:out_trade_no;type:varchar(255);default:'';comment:商户订单号"`
	PrepayId    string    `json:"prepay_id" gorm:"column:prepay_id;type:varchar(50);default:'';comment:预支付交易会话ID"`
	TimeStamp   string    `json:"time_stamp" gorm:"column:time_stamp;type:varchar(50);default:'';comment:时间戳"`
	NonceStr    string    `json:"nonce_str" gorm:"column:nonce_str;type:varchar(50);default:'';comment:随机字符串,不长于32位"`
	Package     string    `json:"package" gorm:"column:package;type:varchar(255);default:'';comment:订单详情扩展字符串"`
	SignType    string    `json:"sign_type" gorm:"column:sign_type;type:varchar(50);default:'';comment:签名类型"`
	PaySign     string    `json:"pay_sign" gorm:"column:pay_sign;type:text;comment:签名"`
}

func (WxPay) TableName() string { return "wx_pay" }

// 创建支付记录
func (m WxPay) CreateWxPay(database *db.DB, wxPay WxPay) error {
	return database.Create(&wxPay).Error
}

// 更新支付记录
func (m WxPay) UpdateWxPaySuccess(database *db.DB, wxPay WxPay) error {
	var (
		user       Users
		topupWays  TopupWays
		score      int
		scoreInfo  Score
		amountRate float64
	)
	rateStr := viper.GetString("upUserGive.amountRate")
	amountRate, err := strconv.ParseFloat(rateStr, 64)
	if err != nil {
		return err
	}

	// 开启事务
	tx := database.Begin()

	// 查询用户信息,充值方式,并计算积分
	errUser := tx.Model(user).Where("id = ?", wxPay.UserID).First(&user).Error
	if errUser != nil {
		return errUser
	}
	if wxPay.TopupWaysId > 0 {
		errTopupWays := tx.Model(topupWays).Where("id = ?", wxPay.TopupWaysId).First(&topupWays).Error
		if errTopupWays != nil {
			return errTopupWays
		}

		// 积分
		score = topupWays.Score
	} else {
		score = int(wxPay.AmountTotal / 10)
	}

	// 新增用户积分记录
	scoreInfo.UserId = uint(wxPay.UserID)
	scoreInfo.Score = score
	scoreInfo.Comment = "充值" + fmt.Sprintf("%.2f", float64(wxPay.AmountTotal)/100) + "元"
	scoreInfo.ScoreType = 0
	errScore := tx.Model(&scoreInfo).Create(&scoreInfo).Error
	if errScore != nil {
		tx.Rollback() // 事务回滚
		return errScore
	}

	// 更新用户积分
	oldScore := user.Score
	user.Score += score
	errUserScore := tx.Model(&user).Where("id = ?", wxPay.UserID).Where("score = ?", oldScore).Updates(&user).Error
	if errUserScore != nil {
		tx.Rollback() // 事务回滚
		return errUserScore
	}

	// 查看是否有邀请人,赠送邀请比例金额
	if user.InviteUserID > 0 && amountRate > 0 {
		// 查询是否已赠送过金额,已赠送了就跳过
		var usedBusiness Business
		err = tx.Model(usedBusiness).Where("user_id = ?", user.InviteUserID).Where("type = ?", BusinessTypes["invite-02"]).Where("invite_user_id = ?", user.ID).First(&usedBusiness).Error
		if err == nil {
			return nil
		}

		// 计算赠送金额
		giveAmount := int(float64(amountRate)*float64(wxPay.AmountTotal)) / 100
		if giveAmount > 0 && usedBusiness.ID == 0 {
			// 先给0号用户佣金,然后再给邀请人佣金
			business0 := Business{
				UserId:  0,
				Amount:  float64(-giveAmount),
				Type:    BusinessTypes["invite-02"],
				Comment: user.Username + "充值佣金返现",
				FromId:  int64(wxPay.UserID),
			}
			err := business0.Create(database)
			if err != nil {
				return err
			}
			business := Business{
				UserId:       int64(user.InviteUserID),
				Amount:       float64(giveAmount),
				Type:         BusinessTypes["invite-02"],
				Comment:      user.Username + "充值佣金返现",
				FromId:       0,
				InviteUserId: int64(user.ID),
			}
			err = business.Create(database)
			if err != nil {
				return err
			}
		}
	}

	// 更新状态
	wxPay.TradeState = "SUCCESS"
	wxPay.SuccessTime = time.Now()
	errWxPay := database.Model(&wxPay).Where("trade_state != ?", "SUCCESS").Updates(&wxPay).Error
	if errWxPay != nil {
		tx.Rollback() // 事务回滚
		return errWxPay
	}

	// 提交事务
	tx.Commit()
	return nil
}

// 跟据out_trade_no查询支付记录
func (m WxPay) GetWxPayByOutTradeNo(database *db.DB, outTradeNo string) (WxPay, error) {
	var wxPay WxPay
	err := database.Where("out_trade_no = ?", outTradeNo).First(&wxPay).Error
	return wxPay, err
}
